package com.lidroid.xutils.bitmap.core;

import ohos.media.image.PixelMap;
import ohos.media.image.ImageSource;
import com.lidroid.xutils.bitmap.download.Downloader;
import com.lidroid.xutils.util.LogUtils;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;

public class BitmapDownloadProcess {
    private boolean mHttpDiskCacheStarting = true;
    private int cacheSize;
    private static final int DEFAULT_CACHE_SIZE = 20 * 1024 * 1024; // 20MB

    private LruDiskCache mOriginalDiskCache;//原始图片的路径，不进行任何的压缩操作
    private final Object mHttpDiskCacheLock = new Object();
    private static final int DISK_CACHE_INDEX = 0;

    private File mOriginalCacheDir;
    private Downloader downloader;

    private boolean neverCalculate = false;

    public BitmapDownloadProcess(Downloader downloader, String filePath, int cacheSize) {
        this.mOriginalCacheDir = new File(filePath + "/original");
        this.downloader = downloader;
        if (cacheSize <= 0)
            cacheSize = DEFAULT_CACHE_SIZE;
        this.cacheSize = cacheSize;
    }

    public void configCalculateBitmap(boolean neverCalculate) {
        this.neverCalculate = neverCalculate;
    }

    public PixelMap downloadBitmap(String uri, BitmapDisplayConfig config) {
        final String diskKey = FileNameGenerator.generator(uri);
        FileDescriptor fileDescriptor = null;
        FileInputStream fileInputStream = null;
        LruDiskCache.Snapshot snapshot;
        synchronized (mHttpDiskCacheLock) {
            // Wait for disk cache to initialize
            while (mHttpDiskCacheStarting) {
                try {
                    mHttpDiskCacheLock.wait();
                } catch (InterruptedException e) {
                }
            }

            if (mOriginalDiskCache != null) {
                try {
                    snapshot = mOriginalDiskCache.get(diskKey);
                    if (snapshot == null) {
                        LruDiskCache.Editor editor = mOriginalDiskCache.edit(diskKey);
                        if (editor != null) {
                            if (downloader.downloadToLocalStreamByUrl(uri, editor.newOutputStream(DISK_CACHE_INDEX))) {
                                editor.commit();
                            } else {
                                editor.abort();
                            }
                        }
                        snapshot = mOriginalDiskCache.get(diskKey);
                    }
                    if (snapshot != null) {
                        fileInputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);
                        fileDescriptor = fileInputStream.getFD();
                    }
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                } catch (IllegalStateException e) {
                    LogUtils.e(e.getMessage());
                } finally {
                    if (fileDescriptor == null && fileInputStream != null) {
                        try {
                            fileInputStream.close();
                        } catch (IOException e) {
                        }
                    }
                }
            }
        }

        PixelMap bitmap = null;
        if (fileDescriptor != null) {
            if (neverCalculate)
            {
                //bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
                ImageSource imageSource=ImageSource.create(fileDescriptor,null);
                bitmap=imageSource.createPixelmap(null);
            }
            else
                bitmap = BitmapDecoder.decodeSampledBitmapFromDescriptor(fileDescriptor, config.getBitmapWidth(), config.getBitmapHeight());
        }
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
            }
        }
        return bitmap;
    }

    public void initHttpDiskCache() {
        if (!mOriginalCacheDir.exists()) {
            mOriginalCacheDir.mkdirs();
        }
        synchronized (mHttpDiskCacheLock) {
            if (BitmapCommonUtils.getAvailableSpace(mOriginalCacheDir) > cacheSize) {
                try {
                    mOriginalDiskCache = LruDiskCache.open(mOriginalCacheDir, 1, 1, cacheSize);
                } catch (IOException e) {
                    mOriginalDiskCache = null;
                }
            }
            mHttpDiskCacheStarting = false;
            mHttpDiskCacheLock.notifyAll();
        }
    }

    public void clearCacheInternal() {
        synchronized (mHttpDiskCacheLock) {
            if (mOriginalDiskCache != null && !mOriginalDiskCache.isClosed()) {
                try {
                    mOriginalDiskCache.delete();
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                }
                mOriginalDiskCache = null;
                mHttpDiskCacheStarting = true;
                initHttpDiskCache();
            }
        }
    }

    public void flushCacheInternal() {
        synchronized (mHttpDiskCacheLock) {
            if (mOriginalDiskCache != null) {
                try {
                    mOriginalDiskCache.flush();
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                }
            }
        }
    }

    public void closeCacheInternal() {
        synchronized (mHttpDiskCacheLock) {
            if (mOriginalDiskCache != null) {
                try {
                    if (!mOriginalDiskCache.isClosed()) {
                        mOriginalDiskCache.close();
                        mOriginalDiskCache = null;
                    }
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                }
            }
        }
    }


}
